home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 15 / BBS in a box XV-2.iso / Files II / Prog / M / MacPerl 4.13 source.sit / Perl Source ƒ / MacPerl / MPSave.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-27  |  8.6 KB  |  426 lines  |  [TEXT/MPS ]

  1. /*********************************************************************
  2. Project    :    MacPerl            -    Real Perl Application
  3. File        :    MPSave.c            -    Handle all the runtimes
  4. Author    :    Matthias Neeracher
  5.  
  6. A lot of this code is borrowed from 7Edit written by
  7. Apple Developer Support UK
  8.  
  9. Language    :    MPW C
  10.  
  11. $Log: MPSave.c,v $
  12. Revision 1.1  1994/02/27  23:01:45  neeri
  13. Initial revision
  14.  
  15. Revision 0.1  1993/10/03  00:00:00  neeri
  16. Compiles correctly
  17.  
  18. *********************************************************************/
  19.  
  20. #include <Errors.h>
  21. #include <Resources.h>
  22. #include <PLStringFuncs.h>
  23. #include <SysEqu.h>
  24. #include <Folders.h>
  25.  
  26. #include "MPSave.h"
  27. #include "MPGlobals.h"
  28. #include "MPFile.h"
  29. #include "MPUtils.h"
  30.  
  31. #pragma segment File
  32.  
  33. OSErr DoOpenResFile(FSSpec * spec, short * resFile, Boolean bundle)
  34. {
  35.     OSErr    err;
  36.     
  37.     *resFile = HOpenResFile(spec->vRefNum, spec->parID, spec->name, fsRdWrPerm);
  38.     if (*resFile == -1) {
  39.         if (err = DoCreate(*spec))
  40.             return err;
  41.  
  42.         *resFile =  HOpenResFile(spec->vRefNum, spec->parID, spec->name, fsRdWrPerm);
  43.         if (*resFile == -1) {
  44.             FileError("\perror opening file ", spec->name);
  45.             
  46.             return ResError();
  47.         }
  48.     }
  49.     
  50.     if (bundle) {
  51.         FInfo info;
  52.         
  53.         HGetFInfo(spec->vRefNum, spec->parID, spec->name, &info);
  54.         info.fdType        =    'APPL';
  55.         info.fdCreator    =    MPRtSig;
  56.         info.fdFlags     |= fHasBundle;
  57.         HSetFInfo(spec->vRefNum, spec->parID, spec->name, &info);
  58.     }
  59.     
  60.     return noErr;
  61. }
  62.  
  63. typedef struct {
  64.     OSType    type;
  65.     short        id;
  66.     OSType    realType;
  67. } ShoppingList;
  68.  
  69. OSErr    CopyShoppingList(short from, short to, ShoppingList * list)
  70. {
  71.     OSErr    err;
  72.     
  73.     while (list->type) {
  74.         Handle    rsrc;
  75.         Handle    nur;
  76.         
  77.         UseResFile(from);
  78.         
  79.         rsrc = Get1Resource(list->type, list->id);
  80.         
  81.         if (!rsrc)
  82.             return ResError();
  83.         
  84.         UseResFile(to);
  85.         
  86.         if (nur = Get1Resource(list->realType, list->id))
  87.             RmveResource(nur);
  88.             
  89.         DetachResource(rsrc);
  90.         AddResource(rsrc, list->realType, list->id, "\p");
  91.         
  92.         if (err = ResError())
  93.             goto finish;
  94.         
  95.         ++list;
  96.     }
  97.     
  98. finish:
  99.     UseResFile(from);
  100.     
  101.     return err;
  102. }
  103.  
  104. OSErr CopyRsrc(FSSpec * from, FSSpec * to)
  105. {
  106.     OSErr        err;
  107.     short     res;
  108.     short        fromRef;
  109.     short        toRef;
  110.     Handle    copy;
  111.     Ptr        buffer;
  112.     long        len;
  113.     
  114.     copy         = NewHandle(4096);
  115.     buffer     = *copy;
  116.     HLock(copy);
  117.     
  118.     if (err = DoOpenResFile(to, &res, true))
  119.         goto disposeBuffer;
  120.     
  121.     CloseResFile(res);
  122.     
  123.     if (err = HOpenRF(from->vRefNum, from->parID, from->name, fsRdPerm, &fromRef))
  124.         goto disposeBuffer;
  125.     if (err = HOpenRF(to->vRefNum, to->parID, to->name, fsRdWrPerm, &toRef))
  126.         goto closeFrom;
  127.  
  128.     do {
  129.         len    =    4096;
  130.         
  131.         FSRead(fromRef, &len, buffer);
  132.         FSWrite(toRef, &len, buffer);
  133.     } while (len == 4096);
  134.     
  135.     FSClose(toRef);
  136.     
  137. closeFrom:
  138.     FSClose(fromRef);
  139. disposeBuffer:
  140.     DisposeHandle(copy);
  141.     
  142.     return err;
  143. }
  144.  
  145. ShoppingList DropletShopping[] =
  146. {
  147.     { 'MrPC',    0, 'CODE' },
  148.     { 'MrPC',    1, 'CODE' },
  149.     { 'MrPC',    2, 'CODE' },
  150.     { 'MrPB',  128, 'BNDL' },
  151.     { 'MrPL',    0, 'MrPL' },
  152.     { 'MrPS',   -1, 'SIZE' },
  153.     { 'MrPI',  128, 'ICN#' },
  154.     { 'MrP4',  128, 'icl4' },
  155.     { 'MrP8',  128, 'icl8' },
  156.     { 'MrP#',  128, 'ics#' },
  157.     { 'MrPA', 4096, 'ALRT' },
  158.     { 'MrPD', 4096, 'DITL' },
  159.     { 'FREF',  128, 'FREF' },
  160.     { 'FREF',  129, 'FREF' },
  161.     { 'FREF',  131, 'FREF' },
  162.     { 'MrPF',  132, 'FREF' },
  163.     { 'MrPF',  133, 'FREF' },
  164.     { 'MrPF',  134, 'FREF' },
  165.     {          0,    0,      0 }
  166. };
  167.  
  168. OSErr MakeDroplet(FSSpec * spec, short * resFile)
  169. {
  170.     OSErr    err;
  171.     
  172.     if (err = DoOpenResFile(spec, resFile, true))
  173.         return err;
  174.     
  175.     return CopyShoppingList(gAppFile, *resFile, DropletShopping);
  176. }
  177.  
  178. OSErr Make6Runtime(FSSpec * spec, short * resFile)
  179. {
  180.     OSErr        err;
  181.     FSSpec    from;
  182.     
  183.     from.vRefNum    =    gAppVol;
  184.     from.parID        =    gAppDir;
  185.     PLstrcpy(from.name, "\pMacPerl Runtime");
  186.     
  187.     if (!CopyRsrc(&from, spec))
  188.         return DoOpenResFile(spec, resFile, false);
  189.     
  190.     err = 
  191.         FindFolder(
  192.             kOnSystemDisk, 
  193.             kPreferencesFolderType, 
  194.             true, 
  195.             &from.vRefNum,
  196.             &from.parID);
  197.     
  198.     if (err || (err = CopyRsrc(&from, spec))) {
  199.         DialogPtr    dlg;
  200.         short            item;
  201.         
  202.         ParamText(    
  203.             "\pTo create System 6 compatible Perl runtimes, I need"
  204.             "\"MacPerl Runtime\" in the same folder as this application or"
  205.             "in the preferences folder.", "\pOK", "\p", "\p");
  206.         
  207.         dlg = GetNewDialog(2001, (WindowPtr) nil, (WindowPtr) -1);
  208.         ShowWindow(dlg);
  209.         ModalDialog(nil, &item);
  210.         DisposeDialog(dlg);
  211.         
  212.         return userCanceledErr;
  213.     }
  214.         
  215.     return DoOpenResFile(spec, resFile, false);
  216. }
  217.  
  218. ShoppingList Runtime7Shopping[] =
  219. {
  220.     { 'MrPB',  128, 'BNDL' },
  221.     { 'MrPI',  128, 'ICN#' },
  222.     { 'MrP4',  128, 'icl4' },
  223.     { 'MrP8',  128, 'icl8' },
  224.     { 'MrP#',  128, 'ics#' },
  225.     { 'MrPF',  132, 'FREF' },
  226.     { 'MrPF',  133, 'FREF' },
  227.     { 'MrPF',  134, 'FREF' },
  228.     {          0,    0,      0 }
  229. };
  230.  
  231. OSErr Make7Runtime(FSSpec * spec, short * resFile)
  232. {
  233.     OSErr        err;
  234.     FSSpec    from;
  235.     
  236.     from.vRefNum    =    gAppVol;
  237.     from.parID        =    gAppDir;
  238.     PLstrcpy(from.name, (StringPtr) CurApName);
  239.  
  240.     if (err = CopyRsrc(&from, spec))
  241.         return err;
  242.         
  243.     if (err = DoOpenResFile(spec, resFile, false))
  244.         return err;
  245.         
  246.     return CopyShoppingList(gAppFile, *resFile, Runtime7Shopping);
  247. }
  248.  
  249. #ifdef RUNTIME
  250. #define HOpenDF    HOpen
  251. #endif
  252.  
  253. pascal OSErr DoSave(DPtr theDocument, FSSpec theFSSpec)
  254. {
  255.     OSErr               err;
  256.     short                resFile;
  257.     OSType            type;
  258.     Handle            text    =     (*(theDocument->theText))->hText;
  259.     Handle            thePHandle;
  260.     HHandle            theHHandle;
  261.     StringHandle    theAppName;
  262.  
  263.     HDelete(theFSSpec.vRefNum, theFSSpec.parID, theFSSpec.name);
  264.     
  265.     switch (theDocument->type) {
  266.     case kPlainTextDoc:
  267.         {
  268.             short        refNum;
  269.             long        length;
  270.             
  271.         if (err = DoOpenResFile(&theFSSpec, &resFile, false))
  272.             return err;
  273.             
  274.         if (err = 
  275.                 HOpenDF(
  276.                     theFSSpec.vRefNum, theFSSpec.parID, theFSSpec.name,
  277.                     fsRdWrPerm, &refNum)
  278.             ) {
  279.                 if (err = DoCreate(theFSSpec))
  280.                     goto closeResource;
  281.                 
  282.                 if (err =
  283.                     HOpenDF(
  284.                         theFSSpec.vRefNum, theFSSpec.parID, theFSSpec.name,
  285.                         fsRdWrPerm, &refNum)
  286.                 ) {
  287.                     FileError("\perror opening file ", theFSSpec.name);
  288.                     
  289.                     goto closeResource;
  290.                 }
  291.             }
  292.             
  293.             length     = GetHandleSize(text);
  294.             
  295.             HLock(text);
  296.             
  297.             err = FSWrite(refNum, &length, *text);
  298.             
  299.             HUnlock(text);
  300.             FSClose(refNum);
  301.             
  302.             if (err)
  303.                 goto closeResource;
  304.         }
  305.         break;
  306.     case kScriptDoc:
  307.         if (err = MakeDroplet(&theFSSpec, &resFile))
  308.             return err;
  309.         
  310.         type = 'SCPT';
  311.         
  312.         goto writeScript;
  313.     case kRuntime6Doc:
  314.         if (err = Make6Runtime(&theFSSpec, &resFile))
  315.             return err;
  316.         
  317.         type = 'MrP6';
  318.         
  319.         goto writeScript;
  320.     case kRuntime7Doc:
  321.         if (err = Make7Runtime(&theFSSpec, &resFile))
  322.             return err;
  323.         
  324.         type = 'MrP7';
  325.         
  326. writeScript:            
  327.         if (err = HandToHand(&text))
  328.             goto closeResource;
  329.         
  330.         UseResFile(resFile);
  331.         
  332.         AddResource(text, 'TEXT', 128, "\p!");
  333.         if (err = ResError()) {
  334.             DisposeHandle(text);
  335.             
  336.             goto closeResource;
  337.         }
  338.         
  339.         if (err = PtrToHand(&type, &text, 4))
  340.             goto closeResource;
  341.         
  342.         AddResource(text, 'MrPL', 128, "\p");
  343.         if (err = ResError()) {
  344.             DisposeHandle(text);
  345.             
  346.             goto closeResource;
  347.         }
  348.             
  349.         break;
  350.     }
  351.     
  352.     /* write out the printer info */
  353.     if (theDocument->thePrintSetup) {
  354.         thePHandle = (Handle)theDocument->thePrintSetup;
  355.         HandToHand(&thePHandle);
  356.  
  357.         AddResource(thePHandle, 'TFSP', 255, "\pPrinter Info");
  358.         err = ResError();
  359.         if (err = ResError()) {
  360.             ShowError("\pAddResource TFSP", err);
  361.             return err;
  362.         }
  363.     }
  364.  
  365.     theHHandle = (HHandle)NewHandle(sizeof(HeaderRec));
  366.      HLock((Handle)theHHandle);
  367.  
  368.     (*theHHandle)->theRect     = theDocument->theWindow->portRect;
  369.     OffsetRect(
  370.         &(*theHHandle)->theRect,
  371.         -theDocument->theWindow->portBits.bounds.left,
  372.         -theDocument->theWindow->portBits.bounds.top);
  373.         
  374.     GetFontName((*(theDocument->theText))->txFont, &(*theHHandle)->theFont);
  375.     
  376.     (*theHHandle)->theSize     = (*(theDocument->theText))->txSize;
  377.     (*theHHandle)->lastID      = theDocument->kind == kDocumentWindow ? theDocument->u.reg.lastID : 0;
  378.     (*theHHandle)->numSections = theDocument->kind == kDocumentWindow ? theDocument->u.reg.numSections : 0;
  379.  
  380.     HUnlock((Handle)theHHandle);
  381.  
  382.     AddResource((Handle)theHHandle, 'TFSS', 255, "\pHeader Info");
  383.     if (err = ResError()) {
  384.         ShowError("\pAddResource- TFSS", err);
  385.         return err;
  386.     }
  387.  
  388. #ifndef RUNTIME
  389.     /*if we have any sections, write out the records and resources*/
  390.  
  391.     if (theDocument->kind == kDocumentWindow && theDocument->u.reg.numSections) {
  392.         /*now write out the section records*/
  393.         SaveSections(theDocument);
  394.  
  395.         /*write the latest versions of all editions to their containers*/
  396.  
  397.         WriteAllEditions(theDocument);
  398.     }
  399. #endif
  400.  
  401.     if (theDocument->type == kPlainTextDoc) {
  402.         /*Now put an AppName in for Finder in 7.0*/
  403.     
  404.         theAppName = (StringHandle)NewHandle(8);
  405.         PLstrcpy(*theAppName,"\pMacPerl");
  406.     
  407.         AddResource((Handle)theAppName, 'STR ', - 16396, "\pFinder App Info");
  408.         if (err = ResError()) {
  409.             ShowError("\pAppName", err);
  410.             return err;
  411.         }
  412.     }
  413.     
  414.     if (theDocument->kind == kDocumentWindow) {
  415.         theDocument->dirty = false;
  416.         theDocument->u.reg.everSaved = true;
  417.     }
  418.  
  419. closeResource:
  420.     CloseResFile(resFile);
  421.     UseResFile(gAppFile);
  422.     
  423.     return err;
  424. }
  425.  
  426.